home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / drawpix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  24.7 KB  |  959 lines

  1. /* drawpix.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: drawpix.c,v 1.18 1995/11/09 15:15:29 brianp Exp $
  26.  
  27. $Log: drawpix.c,v $
  28.  * Revision 1.18  1995/11/09  15:15:29  brianp
  29.  * allow glDrawPixels width and height to be zero
  30.  *
  31.  * Revision 1.17  1995/11/03  17:41:17  brianp
  32.  * fixed a few things for C++ compilation
  33.  *
  34.  * Revision 1.16  1995/10/19  15:48:51  brianp
  35.  * replaced a for loop with MEMSET
  36.  *
  37.  * Revision 1.15  1995/10/16  15:25:49  brianp
  38.  * added zooming for stencil drawing/copying
  39.  *
  40.  * Revision 1.14  1995/10/14  16:28:07  brianp
  41.  * added glPixelZoom support
  42.  *
  43.  * Revision 1.13  1995/09/28  16:18:48  brianp
  44.  * replaced a loop in draw_color_pixels with a MEMSET
  45.  *
  46.  * Revision 1.12  1995/09/15  18:46:10  brianp
  47.  * directly call DD.write_color_span under right conditions
  48.  *
  49.  * Revision 1.11  1995/07/24  20:35:20  brianp
  50.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  51.  *
  52.  * Revision 1.10  1995/07/24  18:59:42  brianp
  53.  * convert real window coords to ints with rounding, not truncating
  54.  *
  55.  * Revision 1.9  1995/06/12  15:53:40  brianp
  56.  * removed garbage chars from end of file
  57.  *
  58.  * Revision 1.8  1995/06/12  15:50:44  brianp
  59.  * renamed from drawpixels.[ch] to drawpix.[ch]
  60.  *
  61.  * Revision 1.7  1995/06/12  15:38:55  brianp
  62.  * changed color arrays to GLubyte
  63.  *
  64.  * Revision 1.6  1995/05/31  14:58:26  brianp
  65.  * check that rasterpos is valid before drawing
  66.  *
  67.  * Revision 1.5  1995/05/22  21:02:41  brianp
  68.  * Release 1.2
  69.  *
  70.  * Revision 1.4  1995/05/12  19:26:43  brianp
  71.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  72.  *
  73.  * Revision 1.3  1995/05/10  18:43:58  brianp
  74.  * removed extraneous parenthesis
  75.  * moved clip_pixels() to span.c
  76.  *
  77.  * Revision 1.2  1995/03/04  19:29:44  brianp
  78.  * 1.1 beta revision
  79.  *
  80.  * Revision 1.1  1995/02/24  14:20:50  brianp
  81.  * Initial revision
  82.  *
  83.  */
  84.  
  85.  
  86. #include <stdlib.h>
  87. #include <string.h>
  88. #include "context.h"
  89. #include "dd.h"
  90. #include "feedback.h"
  91. #include "list.h"
  92. #include "macros.h"
  93. #include "pixel.h"
  94. #include "span.h"
  95. #include "stencil.h"
  96.  
  97.  
  98.  
  99.  
  100. /* TODO:  apply texture mapping to fragments */
  101.  
  102.  
  103.  
  104. static void draw_index_pixels( GLsizei width, GLsizei height,
  105.                    GLenum type, const GLvoid *pixels )
  106. {
  107.    GLint x, y, desty;
  108.    GLuint i, j;
  109.    GLint zspan[MAX_WIDTH];
  110.    GLboolean zoom;
  111.  
  112.    if (CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0) {
  113.       zoom = GL_FALSE;
  114.    }
  115.    else {
  116.       zoom = GL_TRUE;
  117.    }
  118.  
  119.    /* Position, depth of pixels */
  120.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  121.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  122.    desty = y;
  123.    if (CC.Depth.Test) {
  124.       GLint zval = (GLint) (CC.Current.RasterPos[2] * MAX_DEPTH);
  125.       for (i=0;i<width;i++) {
  126.      zspan[i] = zval;
  127.       }
  128.    }
  129.  
  130.    /* process the image row by row */
  131.    for (i=0;i<height;i++,y++) {
  132.       GLuint ispan[MAX_WIDTH];
  133.  
  134.       /* convert to uints */
  135.       switch (type) {
  136.      case GL_UNSIGNED_BYTE:
  137.         {
  138.            GLubyte *src = (GLubyte *) pixels + i * width;
  139.            for (j=0;j<width;j++) {
  140.           ispan[j] = (GLuint) *src++;
  141.            }
  142.         }
  143.         break;
  144.      case GL_BYTE:
  145.         {
  146.            GLbyte *src = (GLbyte *) pixels + i * width;
  147.            for (j=0;j<width;j++) {
  148.           ispan[j] = (GLuint) *src++;
  149.            }
  150.         }
  151.         break;
  152.      case GL_UNSIGNED_SHORT:
  153.         {
  154.            GLushort *src = (GLushort *) pixels + i * width;
  155.            for (j=0;j<width;j++) {
  156.           ispan[j] = (GLuint) *src++;
  157.            }
  158.         }
  159.         break;
  160.      case GL_SHORT:
  161.         {
  162.            GLshort *src = (GLshort *) pixels + i * width;
  163.            for (j=0;j<width;j++) {
  164.           ispan[j] = (GLuint) *src++;
  165.            }
  166.         }
  167.         break;
  168.      case GL_UNSIGNED_INT:
  169.         {
  170.            GLuint *src = (GLuint *) pixels + i * width;
  171.            for (j=0;j<width;j++) {
  172.           ispan[j] = *src++;
  173.            }
  174.         }
  175.         break;
  176.      case GL_INT:
  177.         {
  178.            GLint *src = (GLint *) pixels + i * width;
  179.            for (j=0;j<width;j++) {
  180.           ispan[j] = (GLuint) *src++;
  181.            }
  182.         }
  183.         break;
  184.      case GL_BITMAP:
  185.         /* TODO */
  186.         break;
  187.      case GL_FLOAT:
  188.         {
  189.            GLfloat *src = (GLfloat *) pixels + i * width;
  190.            for (j=0;j<width;j++) {
  191.           ispan[j] = (GLuint) (GLint) *src++;
  192.            }
  193.         }
  194.         break;
  195.      default:
  196.         gl_error( GL_INVALID_ENUM, "Internal: draw_index_pixels" );
  197.       }
  198.  
  199.       /* apply shift and offset */
  200.       if (CC.Pixel.IndexOffset || CC.Pixel.IndexShift) {
  201.      if (CC.Pixel.IndexShift>=0) {
  202.         for (j=0;j<width;j++) {
  203.            ispan[j] = (ispan[j] << CC.Pixel.IndexShift)
  204.                   + CC.Pixel.IndexOffset;
  205.         }
  206.      }
  207.      else {
  208.         for (j=0;j<width;j++) {
  209.            ispan[j] = (ispan[j] >> -CC.Pixel.IndexShift)
  210.                   + CC.Pixel.IndexOffset;
  211.         }
  212.      }
  213.       }
  214.  
  215.       if (CC.RGBAflag) {
  216.      /* Convert index to RGBA and write to frame buffer */
  217.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  218.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  219.      for (j=0;j<width;j++) {
  220.         red[j]   = (GLint) (CC.Pixel.MapItoR[ispan[j]] * CC.RedScale);
  221.         green[j] = (GLint) (CC.Pixel.MapItoG[ispan[j]] * CC.GreenScale);
  222.         blue[j]  = (GLint) (CC.Pixel.MapItoB[ispan[j]] * CC.BlueScale);
  223.         alpha[j] = (GLint) (CC.Pixel.MapItoA[ispan[j]] * CC.AlphaScale);
  224.      }
  225.          if (zoom) {
  226.             gl_write_zoomed_color_span( width, x, y, zspan,
  227.                                         red, green, blue, alpha, desty );
  228.          }
  229.          else {
  230.             gl_write_color_span( width, x, y, zspan,
  231.                                  red, green, blue, alpha, GL_BITMAP );
  232.          }
  233.       }
  234.       else {
  235.      /* optionally apply index map then write to frame buffer */
  236.      if (CC.Pixel.MapColorFlag) {
  237.         for (j=0;j<width;j++) {
  238.            ispan[j] = CC.Pixel.MapItoI[ispan[j]];
  239.         }
  240.      }
  241.          if (zoom) {
  242.             gl_write_zoomed_index_span( width, x, y, zspan, ispan, desty );
  243.          }
  244.          else {
  245.             gl_write_index_span( width, x, y, zspan, ispan, GL_BITMAP );
  246.          }
  247.       }
  248.    }
  249.  
  250. }
  251.  
  252.  
  253.  
  254. static void draw_stencil_pixels( GLsizei width, GLsizei height,
  255.                      GLenum type, const GLvoid *pixels )
  256. {
  257.    GLint x, y, desty;
  258.    GLuint i, j;
  259.    GLboolean zoom;
  260.  
  261.    if (CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0) {
  262.       zoom = GL_FALSE;
  263.    }
  264.    else {
  265.       zoom = GL_TRUE;
  266.    }
  267.  
  268.    /* Position, depth of pixels */
  269.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  270.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  271.    desty = y;
  272.  
  273.    /* process the image row by row */
  274.    for (i=0;i<height;i++,y++) {
  275.       GLubyte stencil[MAX_WIDTH];
  276.  
  277.       /* convert to ubytes */
  278.       switch (type) {
  279.      case GL_UNSIGNED_BYTE:
  280.         {
  281.            GLubyte *src = (GLubyte *) pixels + i * width;
  282.            MEMCPY( stencil, src, width );
  283.         }
  284.         break;
  285.      case GL_BYTE:
  286.         {
  287.            GLbyte *src = (GLbyte *) pixels + i * width;
  288.            MEMCPY( stencil, src, width );
  289.         }
  290.         break;
  291.      case GL_UNSIGNED_SHORT:
  292.         {
  293.            GLushort *src = (GLushort *) pixels + i * width;
  294.            for (j=0;j<width;j++) {
  295.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  296.            }
  297.         }
  298.         break;
  299.      case GL_SHORT:
  300.         {
  301.            GLshort *src = (GLshort *) pixels + i * width;
  302.            for (j=0;j<width;j++) {
  303.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  304.            }
  305.         }
  306.         break;
  307.      case GL_UNSIGNED_INT:
  308.         {
  309.            GLuint *src = (GLuint *) pixels + i * width;
  310.            for (j=0;j<width;j++) {
  311.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  312.            }
  313.         }
  314.         break;
  315.      case GL_INT:
  316.         {
  317.            GLint *src = (GLint *) pixels + i * width;
  318.            for (j=0;j<width;j++) {
  319.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  320.            }
  321.         }
  322.         break;
  323.      case GL_BITMAP:
  324.         /* TODO */
  325.         break;
  326.      case GL_FLOAT:
  327.         {
  328.            GLfloat *src = (GLfloat *) pixels + i * width;
  329.            for (j=0;j<width;j++) {
  330.           stencil[j] = (GLubyte) (((GLint) *src++) & 0xff);
  331.            }
  332.         }
  333.         break;
  334.      default:
  335.         gl_error( GL_INVALID_ENUM, "Internal: draw_stencil_pixels" );
  336.       }
  337.  
  338.       /* apply shift and offset */
  339.       if (CC.Pixel.IndexOffset || CC.Pixel.IndexShift) {
  340.      if (CC.Pixel.IndexShift>=0) {
  341.         for (j=0;j<width;j++) {
  342.            stencil[j] = (stencil[j] << CC.Pixel.IndexShift)
  343.                   + CC.Pixel.IndexOffset;
  344.         }
  345.      }
  346.      else {
  347.         for (j=0;j<width;j++) {
  348.            stencil[j] = (stencil[j] >> -CC.Pixel.IndexShift)
  349.                   + CC.Pixel.IndexOffset;
  350.         }
  351.      }
  352.       }
  353.  
  354.       /* mapping */
  355.       if (CC.Pixel.MapStencilFlag) {
  356.      for (j=0;j<width;j++) {
  357.         stencil[j] = CC.Pixel.MapStoS[ stencil[j] ];
  358.      }
  359.       }
  360.  
  361.       /* write stencil values to stencil buffer */
  362.       if (zoom) {
  363.          gl_write_zoomed_stencil_span( (GLuint) width, x, y, stencil, desty );
  364.       }
  365.       else {
  366.          gl_write_stencil_span( (GLuint) width, x, y, stencil );
  367.       }
  368.    }
  369. }
  370.  
  371.  
  372.  
  373. static void draw_depth_pixels( GLsizei width, GLsizei height,
  374.                    GLenum type, const GLvoid *pixels )
  375. {
  376.    GLint x, y, desty;
  377.    GLuint i, j;
  378.    GLfloat depth[MAX_WIDTH];
  379.    GLint zspan[MAX_WIDTH];
  380.    GLubyte red[MAX_WIDTH], green[MAX_WIDTH], blue[MAX_WIDTH], alpha[MAX_WIDTH];
  381.    GLuint ispan[MAX_WIDTH];
  382.    GLboolean zoom;
  383.  
  384.    if (CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0) {
  385.       zoom = GL_FALSE;
  386.    }
  387.    else {
  388.       zoom = GL_TRUE;
  389.    }
  390.  
  391.    /* Position, depth of pixels */
  392.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  393.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  394.    desty = y;
  395.  
  396.    /* Color or index */
  397.    if (CC.RGBAflag) {
  398.       GLint r, g, b, a;
  399.       r = (GLint) (CC.Current.RasterColor[0] * CC.RedScale);
  400.       g = (GLint) (CC.Current.RasterColor[1] * CC.GreenScale);
  401.       b = (GLint) (CC.Current.RasterColor[2] * CC.BlueScale);
  402.       a = (GLint) (CC.Current.RasterColor[3] * CC.AlphaScale);
  403.       MEMSET( red,   r, width );
  404.       MEMSET( green, g, width );
  405.       MEMSET( blue,  b, width );
  406.       MEMSET( alpha, a, width );
  407.    }
  408.    else {
  409.       for (j=0;j<width;j++) {
  410.      ispan[j] = CC.Current.RasterIndex;
  411.       }
  412.    }
  413.  
  414.    /* process image row by row */
  415.    for (i=0;i<height;i++) {
  416.       switch (type) {
  417.      case GL_UNSIGNED_BYTE:
  418.         {
  419.            GLubyte *src = (GLubyte *) pixels + i * width;
  420.            for (j=0;j<width;j++) {
  421.               depth[j] = UBYTE_TO_FLOAT( *src++ );
  422.            }
  423.         }
  424.         break;
  425.      case GL_BYTE:
  426.         {
  427.            GLbyte *src = (GLbyte *) pixels + i * width;
  428.            for (j=0;j<width;j++) {
  429.               depth[j] = BYTE_TO_FLOAT( *src++ );
  430.            }
  431.         }
  432.         break;
  433.      case GL_UNSIGNED_SHORT:
  434.         {
  435.            GLushort *src = (GLushort *) pixels + i * width;
  436.            for (j=0;j<width;j++) {
  437.               depth[j] = USHORT_TO_FLOAT( *src++ );
  438.            }
  439.         }
  440.         break;
  441.      case GL_SHORT:
  442.         {
  443.            GLshort *src = (GLshort *) pixels + i * width;
  444.            for (j=0;j<width;j++) {
  445.               depth[j] = SHORT_TO_FLOAT( *src++ );
  446.            }
  447.         }
  448.         break;
  449.      case GL_UNSIGNED_INT:
  450.         {
  451.            GLuint *src = (GLuint *) pixels + i * width;
  452.            for (j=0;j<width;j++) {
  453.               depth[j] = UINT_TO_FLOAT( *src++ );
  454.            }
  455.         }
  456.         break;
  457.      case GL_INT:
  458.         {
  459.            GLint *src = (GLint *) pixels + i * width;
  460.            for (j=0;j<width;j++) {
  461.               depth[j] = INT_TO_FLOAT( *src++ );
  462.            }
  463.         }
  464.         break;
  465.      case GL_FLOAT:
  466.         {
  467.            GLfloat *src = (GLfloat *) pixels + i * width;
  468.            for (j=0;j<width;j++) {
  469.               depth[j] = *src++;
  470.            }
  471.         }
  472.         break;
  473.       }
  474.  
  475.       /* apply depth scale and bias */
  476.       if (CC.Pixel.DepthScale!=1.0 || CC.Pixel.DepthBias!=0.0) {
  477.      for (j=0;j<width;j++) {
  478.         depth[j] = depth[j] * CC.Pixel.DepthScale + CC.Pixel.DepthBias;
  479.      }
  480.       }
  481.  
  482.       /* clamp depth values to [0,1] and convert from floats to integers */
  483.       for (j=0;j<width;j++) {
  484.      zspan[j] = (GLint) ( CLAMP( depth[j], 0.0, 1.0 ) * MAX_DEPTH);
  485.       }
  486.       if (CC.RGBAflag) {
  487.          if (zoom) {
  488.             gl_write_zoomed_color_span( width, x, y, zspan,
  489.                                         red, green, blue, alpha, desty );
  490.          }
  491.          else {
  492.             gl_write_color_span( width, x, y, zspan,
  493.                                  red, green, blue, alpha, GL_BITMAP );
  494.          }
  495.       }
  496.       else {
  497.          if (zoom) {
  498.             gl_write_zoomed_index_span( width, x, y, zspan, ispan, GL_BITMAP );
  499.          }
  500.          else {
  501.             gl_write_index_span( width, x, y, zspan, ispan, GL_BITMAP );
  502.          }
  503.       }
  504.  
  505.    }
  506.  
  507. }
  508.  
  509.  
  510.  
  511. static void draw_color_pixels( GLsizei width, GLsizei height, GLenum format,
  512.                    GLenum type, const GLvoid *pixels )
  513. {
  514.    GLuint i, j;
  515.    GLint x, y, desty, zspan[MAX_WIDTH];
  516.    GLboolean scale_or_bias, quick_draw;
  517.    GLboolean zoom;
  518.  
  519.    if (CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0) {
  520.       zoom = GL_FALSE;
  521.    }
  522.    else {
  523.       zoom = GL_TRUE;
  524.    }
  525.  
  526.    /* Position, depth of pixels */
  527.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  528.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  529.    desty = y;
  530.    if (CC.Depth.Test) {
  531.       /* fill in array of z values */
  532.       GLint z = (GLint) (CC.Current.RasterPos[2] * MAX_DEPTH);
  533.       for (i=0;i<width;i++) {
  534.      zspan[i] = z;
  535.       }
  536.    }
  537.  
  538.    /* Determine if scaling and/or biasing is needed */
  539.    if (CC.Pixel.RedScale!=1.0F   || CC.Pixel.RedBias!=0.0F ||
  540.        CC.Pixel.GreenScale!=1.0F || CC.Pixel.GreenBias!=0.0F ||
  541.        CC.Pixel.BlueScale!=1.0F  || CC.Pixel.BlueBias!=0.0F ||
  542.        CC.Pixel.AlphaScale!=1.0F || CC.Pixel.AlphaBias!=0.0F) {
  543.       scale_or_bias = GL_TRUE;
  544.    }
  545.    else {
  546.       scale_or_bias = GL_FALSE;
  547.    }
  548.  
  549.    /* Determine if we can directly call the device driver function */
  550.    if (CC.RasterMask==0 && !zoom && x>=0 && y>=0
  551.        && x+width<=CC.BufferWidth && y+height<=CC.BufferHeight) {
  552.       quick_draw = GL_TRUE;
  553.    }
  554.    else {
  555.       quick_draw = GL_FALSE;
  556.    }
  557.  
  558.    /* First check for common cases */
  559.    if (type==GL_UNSIGNED_BYTE && format==GL_RGB
  560.        && !CC.Pixel.MapColorFlag && !scale_or_bias
  561.        && CC.RedScale==255.0 && CC.GreenScale==255.0 && CC.BlueScale==255.0) {
  562.       /* 8-bit RGB pixels */
  563.       DEFARRAY( GLubyte, red, MAX_WIDTH );
  564.       DEFARRAY( GLubyte, green, MAX_WIDTH );
  565.       DEFARRAY( GLubyte, blue, MAX_WIDTH );
  566.       DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  567.       GLubyte *src = (GLubyte *) pixels;
  568.       /* constant alpha */
  569.       MEMSET( alpha, (GLint) CC.AlphaScale, width );
  570.       for (i=0;i<height;i++,y++) {
  571.      for (j=0;j<width;j++) {
  572.         red[j]   = *src++;
  573.         green[j] = *src++;
  574.         blue[j]  = *src++;
  575.      }
  576.          if (quick_draw) {
  577.             (*DD.write_color_span)( width, x,y, red, green, blue, alpha, NULL);
  578.          }
  579.          else if (zoom) {
  580.             gl_write_zoomed_color_span( (GLuint) width, x, y, zspan,
  581.                                         red, green, blue, alpha, desty );
  582.          }
  583.          else {
  584.             gl_write_color_span( (GLuint) width, x, y, zspan,
  585.                                  red, green, blue, alpha, GL_BITMAP );
  586.          }
  587.       }
  588.       UNDEFARRAY( red );
  589.       UNDEFARRAY( green );
  590.       UNDEFARRAY( blue );
  591.       UNDEFARRAY( alpha );
  592.    }
  593.    else {
  594.       /* General solution */
  595.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  596.       GLuint components;
  597.  
  598.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  599.       switch (format) {
  600.      case GL_RED:
  601.         r_flag = GL_TRUE;
  602.         components = 1;
  603.         break;
  604.      case GL_GREEN:
  605.         g_flag = GL_TRUE;
  606.         components = 1;
  607.         break;
  608.      case GL_BLUE:
  609.         b_flag = GL_TRUE;
  610.         components = 1;
  611.         break;
  612.      case GL_ALPHA:
  613.         a_flag = GL_TRUE;
  614.         components = 1;
  615.         break;
  616.      case GL_RGB:
  617.         r_flag = g_flag = b_flag = GL_TRUE;
  618.         components = 3;
  619.         break;
  620.      case GL_LUMINANCE:
  621.         l_flag = GL_TRUE;
  622.         components = 1;
  623.         break;
  624.      case GL_LUMINANCE_ALPHA:
  625.         l_flag = a_flag = GL_TRUE;
  626.         components = 2;
  627.         break;
  628.      case GL_RGBA:
  629.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  630.         components = 4;
  631.         break;
  632.       }
  633.  
  634.       /* process the image row by row */
  635.       for (i=0;i<height;i++,y++) {
  636.      GLfloat rf[MAX_WIDTH], gf[MAX_WIDTH], bf[MAX_WIDTH], af[MAX_WIDTH];
  637.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  638.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  639.  
  640.      /* convert to floats */
  641.      switch (type) {
  642.         case GL_UNSIGNED_BYTE:
  643.            {
  644.           GLubyte *src = (GLubyte *) pixels + i * width * components;
  645.           for (j=0;j<width;j++) {
  646.              if (l_flag) {
  647.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  648.              }
  649.              else {
  650.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  651.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  652.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  653.              }
  654.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  655.           }
  656.            }
  657.            break;
  658.         case GL_BYTE:
  659.            {
  660.           GLbyte *src = (GLbyte *) pixels + i * width * components;
  661.           for (j=0;j<width;j++) {
  662.              if (l_flag) {
  663.             rf[j] = gf[j] = bf[j] = BYTE_TO_FLOAT(*src++);
  664.              }
  665.              else {
  666.             rf[j] = r_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  667.             gf[j] = g_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  668.             bf[j] = b_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  669.              }
  670.              af[j] = a_flag ? BYTE_TO_FLOAT(*src++) : 1.0;
  671.           }
  672.            }
  673.            break;
  674.         case GL_BITMAP:
  675.            /* special case */
  676.            break;
  677.         case GL_UNSIGNED_SHORT:
  678.            {
  679.           GLushort *src = (GLushort *) pixels + i * width * components;
  680.           for (j=0;j<width;j++) {
  681.              if (l_flag) {
  682.             rf[j] = gf[j] = bf[j] = USHORT_TO_FLOAT(*src++);
  683.              }
  684.              else {
  685.             rf[j] = r_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  686.             gf[j] = g_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  687.             bf[j] = b_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  688.              }
  689.              af[j] = a_flag ? USHORT_TO_FLOAT(*src++) : 1.0;
  690.           }
  691.            }
  692.            break;
  693.         case GL_SHORT:
  694.            {
  695.           GLshort *src = (GLshort *) pixels + i * width * components;
  696.           for (j=0;j<width;j++) {
  697.              if (l_flag) {
  698.             rf[j] = gf[j] = bf[j] = SHORT_TO_FLOAT(*src++);
  699.              }
  700.              else {
  701.             rf[j] = r_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  702.             gf[j] = g_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  703.             bf[j] = b_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  704.              }
  705.              af[j] = a_flag ? SHORT_TO_FLOAT(*src++) : 1.0;
  706.           }
  707.            }
  708.            break;
  709.         case GL_UNSIGNED_INT:
  710.            {
  711.           GLuint *src = (GLuint *) pixels + i * width * components;
  712.           for (j=0;j<width;j++) {
  713.              if (l_flag) {
  714.             rf[j] = gf[j] = bf[j] = UINT_TO_FLOAT(*src++);
  715.              }
  716.              else {
  717.             rf[j] = r_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  718.             gf[j] = g_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  719.             bf[j] = b_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  720.              }
  721.              af[j] = a_flag ? af[j] = UINT_TO_FLOAT(*src++) : 1.0;
  722.           }
  723.            }
  724.            break;
  725.         case GL_INT:
  726.            {
  727.           GLint *src = (GLint *) pixels + i * width * components;
  728.           for (j=0;j<width;j++) {
  729.              if (l_flag) {
  730.             rf[j] = gf[j] = bf[j] = INT_TO_FLOAT(*src++);
  731.              }
  732.              else {
  733.             rf[j] = r_flag ? INT_TO_FLOAT(*src++) : 0.0;
  734.             gf[j] = g_flag ? INT_TO_FLOAT(*src++) : 0.0;
  735.             bf[j] = b_flag ? INT_TO_FLOAT(*src++) : 0.0;
  736.              }
  737.              af[j] = a_flag ? INT_TO_FLOAT(*src++) : 1.0;
  738.           }
  739.            }
  740.            break;
  741.         case GL_FLOAT:
  742.            {
  743.           GLfloat *src = (GLfloat *) pixels + i * width * components;
  744.           for (j=0;j<width;j++) {
  745.              if (l_flag) {
  746.             rf[j] = gf[j] = bf[j] = *src++;
  747.              }
  748.              else {
  749.             rf[j] = r_flag ? *src++ : 0.0;
  750.             gf[j] = g_flag ? *src++ : 0.0;
  751.             bf[j] = b_flag ? *src++ : 0.0;
  752.              }
  753.              af[j] = a_flag ? *src++ : 1.0;
  754.           }
  755.            }
  756.            break;
  757.         default:
  758.            gl_error( GL_INVALID_ENUM, "glDrawPixels" );
  759.            return;
  760.      }
  761.  
  762.      /* apply scale and bias */
  763.      if (scale_or_bias) {
  764.         for (j=0;j<width;j++) {
  765.            GLfloat r, g, b, a;
  766.            r = rf[j] * CC.Pixel.RedScale   + CC.Pixel.RedBias;
  767.            g = gf[j] * CC.Pixel.GreenScale + CC.Pixel.GreenBias;
  768.            b = bf[j] * CC.Pixel.BlueScale  + CC.Pixel.BlueBias;
  769.            a = af[j] * CC.Pixel.AlphaScale + CC.Pixel.AlphaBias;
  770.            rf[j] = CLAMP( r, 0.0, 1.0 );
  771.            gf[j] = CLAMP( g, 0.0, 1.0 );
  772.            bf[j] = CLAMP( b, 0.0, 1.0 );
  773.            af[j] = CLAMP( a, 0.0, 1.0 );
  774.         }
  775.      }
  776.  
  777.      /* apply pixel mappings */
  778.      if (CC.Pixel.MapColorFlag) {
  779.         for (j=0;j<width;j++) {
  780.            GLint ir, ig, ib, ia;
  781.            ir = (GLint) (rf[j] * (CC.Pixel.MapRtoRsize-1));
  782.            ig = (GLint) (gf[j] * (CC.Pixel.MapGtoGsize-1));
  783.            ib = (GLint) (bf[j] * (CC.Pixel.MapBtoBsize-1));
  784.            ia = (GLint) (af[j] * (CC.Pixel.MapAtoAsize-1));
  785.            rf[j] = CC.Pixel.MapRtoR[ir];
  786.            gf[j] = CC.Pixel.MapGtoG[ig];
  787.            bf[j] = CC.Pixel.MapBtoB[ib];
  788.            af[j] = CC.Pixel.MapAtoA[ia];
  789.         }
  790.      }
  791.  
  792.      /* convert to integers */
  793.      for (j=0;j<width;j++) {
  794.         red[j]   = (GLint) (rf[j] * CC.RedScale);
  795.         green[j] = (GLint) (gf[j] * CC.GreenScale);
  796.         blue[j]  = (GLint) (bf[j] * CC.BlueScale);
  797.         alpha[j] = (GLint) (af[j] * CC.AlphaScale);
  798.      }
  799.  
  800.      /* write to frame buffer */
  801.          if (quick_draw) {
  802.             (*DD.write_color_span)( width, x,y, red, green, blue, alpha, NULL);
  803.          }
  804.          else if (zoom) {
  805.             gl_write_zoomed_color_span( width, x, y, zspan,
  806.                                         red, green, blue, alpha, desty );
  807.          }
  808.          else {
  809.             gl_write_color_span( (GLuint) width, x, y, zspan,
  810.                                  red, green, blue, alpha, GL_BITMAP );
  811.          }
  812.       }
  813.    }
  814.  
  815. }
  816.  
  817.  
  818.  
  819. /*** EXPERIMENTAL:  THIS ISN'T USED YET ***/
  820. #ifdef LEAVEOUT
  821. /*
  822.  * Do a glDrawPixels( w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels ) optimized
  823.  * for the case of no pixel mapping, no scale, no bias, no zoom, default
  824.  * storage mode, no raster ops, and no pixel clipping.
  825.  */
  826. static void quickdraw_rgb( GLsizei width, GLsizei height, const void *pixels )
  827. {
  828.    DEFARRAY( GLubyte, red, MAX_WIDTH );
  829.    DEFARRAY( GLubyte, green, MAX_WIDTH );
  830.    DEFARRAY( GLubyte, blue, MAX_WIDTH );
  831.    DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  832.    GLint i, j;
  833.    GLint x, y;
  834.    GLint bytes_per_row;
  835.  
  836.    bytes_per_row = width * 3 + (width%4);
  837.  
  838.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  839.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  840.  
  841.    /* constant alpha */
  842.    for (j=0;j<width;j++) {
  843.       alpha[j] = (GLint) CC.AlphaScale;
  844.    }
  845.  
  846.    /* write directly to device driver */
  847.    for (i=0;i<height;i++) {
  848.       /* each row of pixel data starts at 4-byte boundary */
  849.       GLubyte *src = (GLubyte *) pixels + i * bytes_per_row;
  850.       for (j=0;j<width;j++) {
  851.          red[j]   = *src++;
  852.          green[j] = *src++;
  853.          blue[j]  = *src++;
  854.       }
  855.       (*DD.write_color_span)( width, x, y+i, red, green, blue, alpha, NULL);
  856.    }
  857.  
  858.    UNDEFARRAY( red );
  859.    UNDEFARRAY( green );
  860.    UNDEFARRAY( blue );
  861.    UNDEFARRAY( alpha );
  862. }
  863. #endif
  864.  
  865.  
  866.  
  867. void gl_drawpixels( GLsizei width, GLsizei height,
  868.             GLenum format, GLenum type, const GLvoid *pixels )
  869. {
  870.    if (INSIDE_BEGIN_END) {
  871.       gl_error( GL_INVALID_OPERATION, "glDrawPixels" );
  872.       return;
  873.    }
  874.  
  875.    if (CC.NewState) {
  876.       gl_update_state();
  877.    }
  878.  
  879.    if (CC.RenderMode==GL_RENDER) {
  880.       if (!CC.Current.RasterPosValid) {
  881.      return;
  882.       }
  883.       switch (format) {
  884.      case GL_COLOR_INDEX:
  885.             draw_index_pixels( width, height, type, pixels );
  886.         break;
  887.      case GL_STENCIL_INDEX:
  888.         draw_stencil_pixels( width, height, type, pixels );
  889.         break;
  890.      case GL_DEPTH_COMPONENT:
  891.         draw_depth_pixels( width, height, type, pixels );
  892.         break;
  893.      case GL_RED:
  894.      case GL_GREEN:
  895.      case GL_BLUE:
  896.      case GL_ALPHA:
  897.      case GL_RGB:
  898.      case GL_LUMINANCE:
  899.      case GL_LUMINANCE_ALPHA:
  900.      case GL_RGBA:
  901.             draw_color_pixels( width, height, format, type, pixels );
  902.         break;
  903.      default:
  904.         gl_error( GL_INVALID_ENUM, "glDrawPixels" );
  905.       }
  906.    }
  907.    else if (CC.RenderMode==GL_FEEDBACK) {
  908.       APPEND_TOKEN( (GLfloat) GL_DRAW_PIXEL_TOKEN );
  909.       gl_feedback_vertex( CC.Current.RasterPos[0],
  910.               CC.Current.RasterPos[1],
  911.               CC.Current.RasterPos[2],
  912.               CC.Current.RasterPos[3],
  913.               CC.Current.Color, CC.Current.Index,
  914.               CC.Current.TexCoord );
  915.    }
  916.    else if (CC.RenderMode==GL_SELECT) {
  917.       /* TODO: verify that this is correct */
  918.       CC.HitFlag = GL_TRUE;
  919.       if (CC.Current.RasterPos[2] < CC.HitMinZ) {
  920.      CC.HitMinZ = CC.Current.RasterPos[2];
  921.       }
  922.       if (CC.Current.RasterPos[2] > CC.HitMaxZ) {
  923.      CC.HitMaxZ = CC.Current.RasterPos[2];
  924.       }
  925.    }
  926. }
  927.  
  928.  
  929.  
  930. void glDrawPixels( GLsizei width, GLsizei height,
  931.            GLenum format, GLenum type, const GLvoid *pixels )
  932. {
  933.    GLvoid *image;
  934.  
  935.    if (width<0 || height<0) {
  936.       gl_error( GL_INVALID_VALUE, "glDrawPixels" );
  937.       return;
  938.    }
  939.  
  940.    image = gl_unpack( width, height, format, type, pixels );
  941.    if (!image) {
  942.       gl_error( GL_OUT_OF_MEMORY, "glDrawPixels" );
  943.       return;
  944.    }
  945.  
  946.    if (CC.CompileFlag) {
  947.       gl_save_drawpixels( width, height, format, type, image );
  948.    }
  949.    if (CC.ExecuteFlag) {
  950.       gl_drawpixels( width, height, format, type, image );
  951.       if (!CC.CompileFlag) {
  952.      /* may discard unpacked image now */
  953.      free( image );
  954.       }
  955.    }
  956. }
  957.  
  958.  
  959.